home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / listings / v_02_04 / 2n04014b < prev    next >
Text File  |  1991-02-09  |  6KB  |  214 lines

  1. /*
  2.  *  VIDEO.C Copyright (C) 1990 by Mark R. Nelson
  3.  *
  4.  * This module contains a rudimentary set of routines to operate a set
  5.  * of non-overlapping display windows.
  6.  */
  7.  
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <stdarg.h>
  11. #include <string.h>
  12. #include <dos.h>
  13. #include "video.h"
  14. /*
  15.  * These are all the line drawing constants defined.
  16.  */
  17. #define UL_CORNER       218
  18. #define UR_CORNER       191
  19. #define LL_CORNER       192
  20. #define LR_CORNER       217
  21. #define UPPER_TEE       194
  22. #define LOWER_TEE       193
  23. #define LEFT_TEE        195
  24. #define RIGHT_TEE       180
  25. #define CENTER_TEE      197
  26. #define HORIZONTAL_LINE 196
  27. #define VERTICAL_LINE   179
  28.  
  29. #define CHAR(w,r,c) \
  30.  (*physical_screen)[(w)->first_row+(r)][(w)->first_col+(c)].character
  31. #define ATTRIBUTE(w,r,c) \
  32.  (*physical_screen)[(w)->first_row+(r)][(w)->first_col+(c)].attribute
  33. #define ELEMENT(w,r,c) \
  34.  (*physical_screen)[(w)->first_row+(r)][(w)->first_col+(c)]
  35.  
  36. WINDOW *current_window=NULL;
  37.  
  38. /*
  39.  * I create a structure so I can write directly to screen as if it were
  40.  * a big array.  That way the compiler takes care of computing the
  41.  * addresses, all I have to do is insert the row and column.
  42.  */
  43. struct video_element {
  44.                      unsigned char character;
  45.                      unsigned char attribute;
  46.                 };
  47.  
  48. struct video_element (far *physical_screen)[25][80];
  49. struct video_element saved_screen[25][80];
  50. COORD saved_row;
  51. COORD saved_col;
  52. static int screen_initialized=0;
  53.  
  54. void window_printf(WINDOW *window ,char *format,...)
  55. {
  56.     char buffer[81];
  57.     va_list args;
  58.     int i;
  59.  
  60.     va_start(args,format);
  61.     vsprintf(buffer,format,args);
  62.     for ( i = 0; i < strlen( buffer ) ; i++ )
  63.    window_putc( window, buffer[ i ] );
  64. }
  65.  
  66. void window_putc( WINDOW *window, char c )
  67. {
  68.     if ( c == 13 )
  69.    window->cursor_col = 0;
  70.     else if (c == 10 ) {
  71.    window->cursor_row++;
  72.    window->cursor_col = 0;
  73.     } else {
  74.    CHAR( window, window->cursor_row, window->cursor_col) = c;
  75.    window->cursor_col++;
  76.     }
  77.     if ( window->cursor_col >= window->width ) {
  78.    window->cursor_col = 0;
  79.    window->cursor_row++;
  80.     }
  81.     if ( window->cursor_row >= window->height ) {
  82.    window->cursor_row--;
  83.    scroll( window );
  84.     }
  85.     if ( window == current_window )
  86.    set_cursor( window->first_row + window->cursor_row,
  87.                window->first_col + window->cursor_col );
  88. }
  89.  
  90. void scroll( WINDOW *window )
  91. {
  92.     int row;
  93.     int col;
  94.  
  95.     for ( row = 0 ; row < ( window->height - 1 ) ; row++ )
  96.    for ( col = 0 ; col < ( window->width ) ; col++ )
  97.        CHAR( window, row, col ) = CHAR( window, row+1, col );
  98.     for ( col = 0 ; col < ( window->width ) ; col++ )
  99.    CHAR( window, window->height-1, col ) = ' ';
  100. }
  101.  
  102. void restore_screen()
  103. {
  104. int row;
  105. int col;
  106.  
  107.     if (screen_initialized != 0 ) {
  108.    for (row=0;row<25;row++)
  109.        for (col=0;col<80;col++)
  110.             (*physical_screen)[row][col]=saved_screen[row][col];
  111.    set_cursor( saved_row, saved_col );
  112.    screen_initialized = 0;
  113.     }
  114. }
  115.  
  116. /*
  117.  * Change the assignment of physical_screen from 0xb8000000L to 0xb0000000L
  118.  * if you are on a monochrome system.
  119.  */
  120. void initialize_screen()
  121. {
  122.     int row;
  123.     int col;
  124.  
  125.     if ( screen_initialized == 0 ) {
  126.    get_cursor( &saved_row, &saved_col );
  127.    physical_screen=(struct video_element (far *)[25][80])0xb8000000L;
  128.    for (row=0;row<25;row++)
  129.        for (col=0;col<80;col++)
  130.        {
  131.             saved_screen[row][col]=(*physical_screen)[row][col];
  132.             (*physical_screen)[row][col].character=' ';
  133.             (*physical_screen)[row][col].attribute=0x1b;
  134.        }
  135.    screen_initialized = 1;
  136.    atexit( restore_screen );
  137.     }
  138. }
  139.  
  140. void set_cursor(COORD row, COORD col)
  141. {
  142.     union REGS inregs;
  143.     union REGS outregs;
  144.  
  145.     inregs.h.dh=row;
  146.     inregs.h.dl=col;
  147.     inregs.h.bh=0;
  148.     inregs.h.ah=2;
  149.     int86( 0x10, &inregs, &outregs );
  150. }
  151.  
  152. void get_cursor( COORD *row, COORD *col )
  153. {
  154.     union REGS inregs;
  155.     union REGS outregs;
  156.  
  157.     inregs.h.ah = 3;
  158.     inregs.h.bh = 0;
  159.     int86( 0x10, &inregs, &outregs );
  160.     *row = outregs.h.dh;
  161.     *col = outregs.h.dl;
  162. }
  163.  
  164. WINDOW *window_open( COORD row, COORD col, COORD width, COORD height )
  165. {
  166.     WINDOW *window;
  167.  
  168.     window = malloc( sizeof( WINDOW ) );
  169.     if (window == NULL ) {
  170.    restore_screen();
  171.    printf( "Allocation failure!\n" );
  172.    exit(1);
  173.     }
  174.     initialize_screen();
  175.     window->first_row = row;
  176.     window->first_col = col;
  177.     window->width = width;
  178.     window->height = height;
  179.     window->cursor_row = 0;
  180.     window->cursor_col = 0;
  181.     current_window = window;
  182.     draw_box( window );
  183.     window_select( window );
  184.     return( window );
  185. }
  186.  
  187. void draw_box( WINDOW *window)
  188. {
  189.     COORD row;
  190.     COORD col;
  191.  
  192.     for ( row = 0 ; row < window->height ; row++ ) {
  193.    CHAR( window, row, -1 ) = VERTICAL_LINE ;
  194.    CHAR( window, row, window->width ) = VERTICAL_LINE;
  195.     }
  196.     for ( col = 0 ; col < window->width ; col++ ) {
  197.    CHAR( window, -1, col ) = HORIZONTAL_LINE;
  198.    CHAR( window, window->height, col ) = HORIZONTAL_LINE;
  199.     }
  200.     CHAR( window, -1,             -1 )            = UL_CORNER;
  201.     CHAR( window, -1,             window->width ) = UR_CORNER;
  202.     CHAR( window, window->height, -1 )            = LL_CORNER;
  203.     CHAR( window, window->height, window->width ) = LR_CORNER;
  204. }
  205.  
  206. void window_select( WINDOW *window )
  207. {
  208.     current_window = window;
  209.     set_cursor( window->first_row + window->cursor_row,
  210.            window->first_col + window->cursor_col );
  211.  
  212. }
  213.  
  214.